{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 字典对象dict\n",
    "dict是python内建的另一个集合对象。与list相同，她的功能也是包含和管理多个对象。但与list不同的是，dict在查找对象时速度更快。\n",
    "\n",
    "如下面的代码，就定义了一个dict对象d。可以看出，\n",
    "- dict中的对象是总是成对出现的，每一对称为一项（item）。下面代码中出现了两对对象，分别是对象对1，‘zhangsan’和对象对2，‘lisi’。\n",
    "- 项（item）中的第一个对象称为key，第二个对象称为value。\n",
    "\n",
    "\n",
    "dict称为字典对象，名字来自于dictionary。你可以把一个dict对象想像成一本字典。那么每一个单词和它的释义就是dict的项。在字典中，我们可以通过单词快速找到它的释义。在dict中，我们可以通过key这个对象，快速地找到它对应的value对象。**注意，在dict中的key对象不能重复**。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'dict'>\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "['__class__',\n",
       " '__contains__',\n",
       " '__delattr__',\n",
       " '__delitem__',\n",
       " '__dir__',\n",
       " '__doc__',\n",
       " '__eq__',\n",
       " '__format__',\n",
       " '__ge__',\n",
       " '__getattribute__',\n",
       " '__getitem__',\n",
       " '__gt__',\n",
       " '__hash__',\n",
       " '__init__',\n",
       " '__iter__',\n",
       " '__le__',\n",
       " '__len__',\n",
       " '__lt__',\n",
       " '__ne__',\n",
       " '__new__',\n",
       " '__reduce__',\n",
       " '__reduce_ex__',\n",
       " '__repr__',\n",
       " '__setattr__',\n",
       " '__setitem__',\n",
       " '__sizeof__',\n",
       " '__str__',\n",
       " '__subclasshook__',\n",
       " 'clear',\n",
       " 'copy',\n",
       " 'fromkeys',\n",
       " 'get',\n",
       " 'items',\n",
       " 'keys',\n",
       " 'pop',\n",
       " 'popitem',\n",
       " 'setdefault',\n",
       " 'update',\n",
       " 'values']"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d ={1:'zhangsan',2:'lisi'}\n",
    "print(type(d))\n",
    "dir(dict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1 定义与基本操作\n",
    "生成字典对象，有一个语法蜜糖，就是大括号“{}”。\n",
    "在dict中，每一个value可以是任意类型的对象，当然也可以是dict类型。但对key有些限制，并要求不能重复，即不能有两项的key相同，这是因为dict的主要功能，就是可以通过key快速地找到对应的value，所以必须保证key的唯一性。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'dict'>\n",
      "zhangsan\n",
      "zhangsan\n",
      "<class 'dict'>\n",
      "[202001, 80, 100]\n",
      "wangwu\n",
      "{1: 'noname', 2: 'noname', 3: 'noname'}\n",
      "not find\n",
      "not find\n"
     ]
    }
   ],
   "source": [
    "#%%writefile aboutDict/introduction.py\n",
    "class1 = {1:'zhangsan', 2:'lisi', 3:'wangwu'}  #生成一个dict对象并命名\n",
    "print(type(class1))\n",
    "\n",
    "print(class1.__getitem__(1))  \n",
    "'''\n",
    "方法__getitem__的功能是检索key对应的value。\n",
    "参数为key\n",
    "返回对应的value。\n",
    "由于key的唯一性，所有结果只能是要么找到并返回key对应的value；要么报错。\n",
    "'''\n",
    "print(class1[1])             #方法__getitem__的语法蜜糖，参数和返回值完全一样\n",
    "\n",
    "#生成一个dict对象，注意：key和value可以是任意类型的对象\n",
    "class2 = {'zhangsan':[202001, 80,100], 'lisi':[202002], 3:'wangwu'}\n",
    "print(type(class2))\n",
    "print(class2['zhangsan'])\n",
    "print(class2[3])\n",
    "\n",
    "class0 = {}    #生成一个空的dict对象的方法\n",
    "class2 = class0.fromkeys([1,2,3],'noname')  \n",
    "'''\n",
    "dict对象的方法fromkeys可以生成一个新的dict对象（注意class2和class0的区别）;\n",
    "参数1为列表，指定所有项的key，\n",
    "参数2是单个对象，即所有项的value都相同，为参数2。\n",
    "'''\n",
    "print(class2)\n",
    "\n",
    "\n",
    "s = class1.get(100,'not find')\n",
    "print(s)\n",
    "'''\n",
    "#方法get功能也是检索key对应的value\n",
    "参数1为key\n",
    "参数2为一个替代对象：当dict中找不到key，则返回替代对象（参数2）\n",
    "注意该方法与__getitem__的区别，两者功能相同，但当所查找的key不存在时，get会返回替代对象，而__getitem__则会报错。\n",
    "\n",
    "'''\n",
    "s = class1.pop(100,'not find')  #与get功能相同，但是会删除key对应的哪一项，即检索且删除\n",
    "print(s)                "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2 遍历\n",
    "将dict对象中的每一项（item）都访问一次，称为遍历操作。这是集合对象的一种常用操作，如list对象也有遍历操作。但是，dict对象本身并没有对应的方法，因此需要设计一段代码来完成。但你也能感觉的到这样的代码具有某种相似性，即不管list，还是dict，它们的遍历代码非常相似。随着编程经验的累积，你遇到这样的情况会更多。这个称为编程模式（paridiag）\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'dict'>\n",
      "<class 'dict_keys'>\n",
      "zhangsan\n",
      "lisi\n",
      "wangwu\n",
      "lisi\n",
      "<class 'int'>\n",
      "zhangsan\n",
      "<class 'int'>\n",
      "lisi\n",
      "<class 'int'>\n",
      "wangwu\n",
      "<class 'int'>\n",
      "lisi\n",
      "<class 'dict_items'>\n",
      "<class 'tuple'>:1 zhangsan\n",
      "<class 'tuple'>:2 lisi\n",
      "<class 'tuple'>:3 wangwu\n",
      "<class 'tuple'>:4 lisi\n",
      "dict_values(['zhangsan', 'lisi', 'wangwu', 'lisi'])\n"
     ]
    }
   ],
   "source": [
    "#%%writefile aboutDict/traverse.py\n",
    "class1 = {1:'zhangsan', 2:'lisi', 3:'wangwu',4:'lisi'}\n",
    "print(type(class1))\n",
    "\n",
    "keys = class1.keys()\n",
    "print(type(keys))\n",
    "for key in keys:\n",
    "    print(class1[key])\n",
    "\n",
    "for key in class1:\n",
    "    print(type(key))\n",
    "    print(class1[key])\n",
    "\n",
    "items = class1.items()    \n",
    "print(type(items))\n",
    "for item in items:\n",
    "    print(type(item),end=':')\n",
    "    print(item[0],item[1])\n",
    "\n",
    "\n",
    "values = class1.values()\n",
    "print(values)    \n",
    "\n",
    "def traverse(pdict):\n",
    "    print('there are {} students in this class'.format(len(pdict)))\n",
    "    for item in pdict.items():\n",
    "        print(item[0],item[1])\n",
    "    return 0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3 修改操作\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'dict'>\n",
      "there are 4 students in this class\n",
      "41 lisi\n",
      "11 zhangsan\n",
      "13 wangwu\n",
      "22 lisi\n",
      "there are 5 students in this class\n",
      "41 lisi\n",
      "11 zhangsi\n",
      "44 wangjiu\n",
      "13 wangwu\n",
      "22 liwu\n",
      "there are 3 students in this class\n",
      "41 lisi\n",
      "44 wangjiu\n",
      "13 wangwu\n",
      "wangwu\n"
     ]
    }
   ],
   "source": [
    "#%%writefile aboutDict/edit.py\n",
    "class1 = {11:'zhangsan', 22:'lisi', 13:'wangwu',41:'lisi'}\n",
    "print(type(class1))\n",
    "traverse(class1)\n",
    "\n",
    "\n",
    "class1[44] = 'wangjiu'   #添加key：value\n",
    "traverse(class1)\n",
    "\n",
    "\n",
    "class1.__setitem__(11,'zhangsi') #修改key对应的value\n",
    "class1[22] = 'liwu'\n",
    "traverse(class1)\n",
    "\n",
    "\n",
    "class1.__delitem__(22)  #删除\n",
    "del class1[11]\n",
    "traverse(class1)\n",
    "\n",
    "\n",
    "s = class1.pop(13,'noname')  #删除，不会报错\n",
    "print(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on wrapper_descriptor:\n",
      "\n",
      "__setitem__(self, key, value, /)\n",
      "    Set self[key] to value.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(dict.__setitem__)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4 复制\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Writing aboutDict/copy.py\n"
     ]
    }
   ],
   "source": [
    "%%writefile aboutDict/copy.py\n",
    "class1 = {11:'zhangsan', 22:'lisi', 13:'wangwu',41:'lisi'}\n",
    "print(type(class1))\n",
    "traverse(class1)\n",
    "\n",
    "class2 = class1.copy()\n",
    "traverse(class2)\n",
    "\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
